<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>使用代理完成验证组件</title>
    <style>
      body {
        padding: 50px;
        background: #34495e;
      }
      input {
        border: solid 10px #ddd;
        height: 30px;
      }
      .error {
        border: solid 10px red;
      }
    </style>
  </head>
  <body>
    <input type="text" validate rule="max:12,min:3" />
    <input type="text" validate rule="max:3,isNumber" />
  </body>
  <script>
    "use strict";
    //验证处理类
    class Validate {
      max(value, len) {
        return value.length <= len;
      }
      min(value, len) {
        return value.length >= len;
      }
      isNumber(value) {
        return /^\d+$/.test(value);
      }
    }
    //代理工厂
    function proxyFactory(target) {
      return new Proxy(target, {
        get(target, key) {
          return target[key];
        },
        set(target, key, el) {
          const rule = el.getAttribute("rule");
          const validate = new Validate();
          let state = rule.split(",").every((rule) => {
            const info = rule.split(":");
            // console.log(el.value);
            return validate[info[0]](el.value, info[1]);
          });
          el.classList[state ? "remove" : "add"]("error");
          if (el.value == "") el.classList.remove("error");
          return true;
        }
      });
    }
    const proxy = proxyFactory(document.querySelectorAll("[validate]"));
    proxy.forEach((item, i) => {
      item.addEventListener("keyup", function() {
        proxy[i] = this;
      });
    });
    // new Validate();
  </script>
</html>
